#ifndef __GND_TASK_H__
#define __GND_TASK_H__

#include <sigc++/signal.h>
#include <sigc++/slot.h>
#include <mutex>

#include "Global.h"

namespace Gnodroid {

    //任务状态
    enum class TaskState {
        PREPARING = 0,
        RUNNING,
        FINNISHED,
        ERROR,
        BREAK,
    };

    //任务类型
    enum class TaskProgressType {
        NONE = 0,       //无具体进度
        PERSENT,        //百分比进度
        COUNT,          //计数进度
    };

    //任务进度
    class TaskProgress
    {
    public:
        int current {0};
        int total {100};

        TaskProgress(int c = 0, int t = 100) {
            current = c; total = t;
        }
    };

    //Task只能在主线程产生和使用，通过引用计数进行内存管理
    /** 任务基类，用于一些在后台执行的过程
     */
    class Task
    {
    public:
        //启动任务
        virtual void start() = 0;

        //获取任务唯一ID
        long getId();
        //获取任务状态
        virtual TaskState getState();
        //获取进度
        virtual TaskProgress getProgress();
        //获取当前显示信息
        virtual std::string getLabel();             //label用于显示信息
        virtual std::string getMessage();           //message用于显示状态
        //获取任务类型
        virtual TaskProgressType getProcessType();
        //是否可以打断
        virtual bool canInterrupt();
        //打断任务
        virtual bool interrupt();

        sigc::signal<void, long, TaskState>
        signal_state_changed();                     //任务状态改变信号

        sigc::signal<void, long, TaskProgress>
        signal_progress_updated();                  //任务进程改变信号

        sigc::signal<void, long, std::string>
        signal_label_changed();
        sigc::signal<void, long, std::string>
        signal_message_changed();

        //简单引用计数，线程安全
        int ref();
        int unref();


    protected:
        Task(TaskProgressType type);

        TaskState m_taskState {TaskState::PREPARING};
        TaskProgress m_taskProgress;
        std::string m_label {"No task"};
        std::string m_mes {"No message"};
        std::mutex m_taskLock;      //任务锁

        sigc::signal<void, long, TaskState> m_signalStateChanged;
        sigc::signal<void, long, TaskProgress> m_signalProgressUpdated;
        sigc::signal<void, long, std::string> m_signalLabelChanged;
        sigc::signal<void, long, std::string> m_signalMessageChanged;

        bool updateState(TaskState state);              //更新任务状态等，该系列函数可以在其他线程使用
        bool updateProgress(TaskProgress progress);
        bool updateProgress(int current, int total);
        bool updateLabel(std::string label);
        bool updateMessage(std::string mes);

    private:
        long m_lUid {0};

        int m_iRefCount {0};        //任务的引用计数

        TaskProgressType m_taskType {TaskProgressType::NONE};
    };

}


#endif
